package com.qd.panda.service.plate;

import com.cdqidi.constant.ConstantDto;
import com.cdqidi.exception.ApiException;
import com.cdqidi.util.MobileUtil;
import com.qd.common.panda.domain.entity.plate.PlateDTO;
import com.qd.common.panda.domain.entity.plate.UserPlateDTO;
import com.qd.common.panda.domain.entity.plate.UserPlateRelationDTO;
import com.qd.common.panda.domain.enums.CarTypeEnum;
import com.qd.common.panda.util.PlateColorUtil;
import com.qd.common.sys.util.SecurityUtils;
import com.qd.hik.dto.HkBaseHttpResp;
import com.qd.hik.dto.driver.HkPlateReq;
import com.qd.hik.dto.driver.HkPlateResp;
import com.qd.hik.service.HkDriverService;
import com.qd.common.panda.domain.entity.hk.HkUserDTO;
import com.qd.panda.model.UserPlateRelation;
import com.qd.panda.service.third.hk.HkUserService;
import com.qd.system.service.user.BaseUserInfoService;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author sjk
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PlateHolderService {
    @Getter
    private final PlateService plateService;
    private final UserPlateRelationService userPlateRelationService;
    private final HkUserService hkUserService;
    private final BaseUserInfoService baseUserInfoService;
    private final HkDriverService hkDriverService;


    @Transactional(rollbackFor = Exception.class)
    public UserPlateRelationDTO save(UserPlateDTO userPlateDto) {
        return save(userPlateDto,true);
    }

    @Transactional(rollbackFor = Exception.class)
    public UserPlateRelationDTO save(UserPlateDTO userPlateDto,boolean isCreateHk) {
        Integer carType = getCarType(userPlateDto);
        String userId = getUser(userPlateDto);
        savePlate(userPlateDto, carType);
        UserPlateRelation userPlateRelation = userPlateRelationService.getUniqueByPlateNumber(userPlateDto.getPlateNumber());
        if (null == userPlateRelation) {
            UserPlateRelationDTO dto = new UserPlateRelationDTO();
            dto.setUserId(userId);
            dto.setPlateNumber(userPlateDto.getPlateNumber());
            if (carType.equals(CarTypeEnum.NEW_ENERGY.getCode())) {
                dto.setAutoConfirmCharge(userPlateDto.getAutoConfirmCharge());
            }
            dto.setAddTime(LocalDateTime.now());
            final UserPlateRelationDTO userPlateRelationDTO = userPlateRelationService.save(dto);
            if(isCreateHk){
                bindHkPlateNumber(userId, userPlateDto);
            }
            dto.freeData();
            return userPlateRelationDTO;
        } else {
            if (!userPlateRelation.getUserId().equals(userId)) {
                String mobile = baseUserInfoService.getById(userPlateRelation.getUserId()).getMobile();
                throw new ApiException(4001, "当前车牌已经被[" + MobileUtil.getMobile(mobile) + "]的用户使用!");
            }
            return userPlateRelationService.modelToDto(userPlateRelation);
        }
    }

    private void bindHkPlateNumber(String userId, UserPlateDTO userPlateDto) {
        //注册海康用户
        HkUserDTO hkUser = hkUserService.createHkUser(userId, SecurityUtils.getLoginUser().getUser().getAppUserExtend().getMobile());
        //到海康查询是否绑定车牌
        HkBaseHttpResp<HkPlateResp> plateRespHkBaseHttpResp = hkDriverService.plates(hkUser.getDriverId());
        if (plateRespHkBaseHttpResp.isSuccess()) {
            List<HkPlateResp.PlateInfo> results = plateRespHkBaseHttpResp.getData().getResults();
            if (null != results && !results.isEmpty()) {
                List<String> plates = results.stream().map(HkPlateResp.PlateInfo::getPlateNo).collect(Collectors.toList());
                if (plates.contains(userPlateDto.getPlateNumber())) {
                    log.info("在海康存在车牌号，无需添加，车牌号: {}", userPlateDto.getPlateNumber());
                    return;
                }
            }
        } else {
            throw new ApiException("查询车牌异常: " + plateRespHkBaseHttpResp.getMsg());
        }

        //绑定车牌
        HkPlateReq hkPlateReq = new HkPlateReq();
        hkPlateReq.setPlateNo(userPlateDto.getPlateNumber());
        hkPlateReq.setDriverId(hkUser.getDriverId());
        hkPlateReq.setPlateColor(PlateColorUtil.pandaToHk(userPlateDto.getVehicleColor()));
        HkBaseHttpResp<?> resp = hkDriverService.addPlate(hkPlateReq);
        hkPlateReq.freeData();
        if (!resp.isSuccess()) {
            throw new ApiException("添加车牌号异常： " + resp.getMsg());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public UserPlateRelationDTO update(UserPlateDTO userPlateDto) {
        final Integer carType = getCarType(userPlateDto);
        savePlate(userPlateDto, carType);
        String rId = userPlateDto.getRId();
        UserPlateRelationDTO plateRelation = userPlateRelationService.getByIdDto(rId);
        if (null == plateRelation) {
            plateRelation = new UserPlateRelationDTO();
            plateRelation.setRId(userPlateDto.getRId());
            plateRelation.setPlateNumber(userPlateDto.getPlateNumber());
            plateRelation.setUserId(getUser(userPlateDto));
            plateRelation.setAddTime(LocalDateTime.now());
            if (carType.equals(CarTypeEnum.NEW_ENERGY.getCode())) {
                plateRelation.setAutoConfirmCharge(userPlateDto.getAutoConfirmCharge());
            }
            return userPlateRelationService.save(plateRelation);
        } else {
            plateRelation.setPlateNumber(userPlateDto.getPlateNumber());
            if (carType.equals(CarTypeEnum.NEW_ENERGY.getCode())) {
                plateRelation.setAutoConfirmCharge(userPlateDto.getAutoConfirmCharge());
            }
            plateRelation.setAddTime(LocalDateTime.now());
            return userPlateRelationService.update(plateRelation);
        }
    }

    private void savePlate(UserPlateDTO userPlateDto, Integer carType) {
        String plateNumber = userPlateDto.getPlateNumber();
        PlateDTO plate = plateService.getByIdDto(plateNumber);
        if (null == plate) {
            plate = new PlateDTO();
            plate.setPlateNumber(plateNumber);
            plate.setCarType(carType);
            plate.setEtcPay(ConstantDto.SF0);
            plate.setAddTime(LocalDateTime.now());
            plate.setVehicleColor(userPlateDto.getVehicleColor());
            plateService.save(plate);
        } else {
            boolean isUpdate = false;
            if (!plate.getCarType().equals(carType)) {
                plate.setCarType(carType);
                isUpdate = true;
            }
            if (null != plate.getVehicleColor() && null != userPlateDto.getVehicleColor()) {
                if (!plate.getVehicleColor().equals(userPlateDto.getVehicleColor())) {
                    plate.setVehicleColor(userPlateDto.getVehicleColor());
                    isUpdate = true;
                }
            }
            if (isUpdate) {
                plateService.update(plate);
            }
        }
        plate.freeData();
    }

    private String getUser(UserPlateDTO userPlateDto) {
        String userId = userPlateDto.getUserId();
        if (!StringUtils.hasLength(userId)) {
            userId = SecurityUtils.getLoginUser().getUserId();
        }
        if (!StringUtils.hasLength(userId)) {
            throw new ApiException("用户ID不能为空");
        }
        return userId;
    }

    private Integer getCarType(UserPlateDTO userPlateDto) {
        Integer carType;
        if (userPlateDto.getPlateNumber().length() == 8) {
            carType = CarTypeEnum.NEW_ENERGY.getCode();
        } else {
            carType = CarTypeEnum.FUEL_CAR.getCode();
        }
        return carType;
    }

}
